#include "util.h"

#include <tiros/tiros.h>

  


#define STKSIZE             (TIROS_MIN_CTXT_SZ + 64)
#define NUM_TASKS	     4


eflag_t notification;
#define ALERT0	0x01
#define ALERT1	0x02


/* Stacks for each of our tasks */
osword_t task_stack[NUM_TASKS][STKSIZE];

void sleep_secs(int s)
{
	trtime_t t;
	secs_to_trtime(s, &t);
	os_wake_at(&t, O_RELATIVE_TIME);
}


void idle_task(void *dummy)
{
	while(1) 
		delayms(1000);
}


void check_err_code(int8_t rc)
{
	tid_t mytid;
	mytid = os_self_tid();
	puthexchar(mytid);
	if (rc == SUCCESS) {
		putstring(" wait succeeded\n");
	} else {
		putstring(" wait failed\n");
	}
}


void R(void *dummy)
{
	int8_t rc;
	flag_t waitflag;
	waitflag = (flag_t) dummy;
	tid_t myid = os_self_tid();
	puthexchar(myid); putstring(" R: waitflag is "); 
	puthexchar(waitflag); putchar('\n');
	
	while(1) {
		rc = eflag_wait(&notification, waitflag, 
				0, 0);
		check_err_code(rc);
		rc = eflag_wait(&notification, waitflag, 0, 0);
		check_err_code(rc);


		rc = eflag_set(&notification, waitflag,
				       O_EFLAG_CLEAR);
		

		rc = eflag_wait(&notification, waitflag, 0, 0);
		check_err_code(rc);
	}
}


void R_combo(void *dummy)
{
	int8_t rc;
	flag_t waitflag = ALERT0 | ALERT1;

	while(1) {
		rc = eflag_wait(&notification, waitflag, 
				0, O_EFLAG_AND);
		check_err_code(rc);
		
		rc = eflag_wait(&notification, waitflag, 
				0, O_EFLAG_OR);
		check_err_code(rc);


	}

}

void S(void *dummy)
{
	while(1) {
		putstring("S setting ALERT0\n");
		(void) eflag_set(&notification, ALERT0, 0);
		delayms(1000);
		putstring("S setting ALERT1\n");
		(void) eflag_set(&notification, ALERT1, 0);
		delayms(1000);
		putstring("S triggering ALERT0|ALERT1\n");
		(void) eflag_set(&notification, ALERT0|ALERT1,
			       O_EFLAG_TRIGGER);

		delayms(3000);

	}
	
}



void platform_init(void);
int main(void) 
{
	tid_t R0tid, R1tid, Rcombotid, S0tid;
	platform_init();

	// --------------------------------------------------
	os_init();

	/* Initialize the event flag */
	eflag_init( &notification, 0);


	/* Priorities as follows:
	 * R0 : 0
	 * R1 : 1
	 * R_combo : 2
	 * S0 : 3 */

	
	/*
	for (i=0; i< NUM_TASKS-1; i++) 
		csem_init(&cs[i], 0);
	*/

	R0tid = os_task_create(R, (osptr_t)(ALERT0),
			       task_stack[0], STKSIZE, 0); 

	R1tid = os_task_create(R, (osptr_t)(ALERT1),
			       task_stack[1], STKSIZE, 1); 

	Rcombotid = os_task_create(R_combo, (osptr_t)0,
			       task_stack[2], STKSIZE, 2); 

	S0tid = os_task_create(S, (osptr_t)0,
			       task_stack[3], STKSIZE, 3); 

	if (R0tid == ILLEGAL_ELEM || R1tid == ILLEGAL_ELEM ||
	    S0tid == ILLEGAL_ELEM || Rcombotid == ILLEGAL_ELEM) {
			putstring("Task create failed");
	}
	os_start();
	putstring("Started OS: Shouldn't reach here\n");
	while (1);
}

